#include <Arduino.h>
#include <vector>
#include <U8g2lib.h>
#include <WIFI.h>
#include <WIFIClient.h>

#include "Rocker_Button.hpp"
#include "Button.hpp"
#include "Menu.hpp"

// 遥感按键引脚
constexpr int x_pin = 34;
constexpr int y_pin = 35;
// 遥感对象
Rocker_Button x_button(std::bind(analogRead, x_pin));
Rocker_Button y_button(std::bind(analogRead, y_pin));

// 独立按键引脚
const int button_nums = 5;
constexpr int button_z = 32;
constexpr int button_1 = 5;
constexpr int button_2 = 18;
constexpr int button_3 = 19;
constexpr int button_4 = 23;
// 按键对象
Buttons<button_nums> buttons;

// OLED对象 全屏缓冲
U8G2_SSD1306_128X64_NONAME_F_HW_I2C oled(U8G2_R0, 22, 21);

// 连接WiFi
const char* password = "xcz12345678";
const char* ip = "192.168.22.1";
const short port = 8080;
// tcp对象
WiFiClient client;

// menu对象
Menu menu;

// code -------------------------------------------------------------------------------------------

void Rocker_Button_init()
{
    // adc分频
    constexpr int adc_resolution = 12;
    // 配置ADC分辨率
    analogReadResolution(adc_resolution);
    // 配置衰减器
    analogSetAttenuation(ADC_11db);
    // 配置引脚
    pinMode(x_pin, INPUT);
    pinMode(y_pin, INPUT);
    // 初始化遥感对象
    x_button.init(0, 1 << adc_resolution);
    y_button.init(0, 1 << adc_resolution);
}

void OLED_init()
{
    oled.begin();
    // 设置总线频率
    oled.setBusClock(4000000);
    // 设置字体
    oled.setFont(u8g2_font_wqy12_t_chinese2);
}

void button_init()
{
    std::vector<int> pins = { button_z, button_1, button_2, button_3, button_4 };
    buttons.init(pins);
}

void setup()
{
    Serial.begin(9600);
    Rocker_Button_init();
    OLED_init();
    button_init();
}

// 将遥感按键值根据不同档位进行映射
void value_map(int& x_value, int& y_value, int level)
{
    // map(value, from_min, from_max, to_min, to_max)
    static int level_range[4][2] = { {0, 0}, {30, -30}, {960, -60}, {100, -100} };
    y_value = map(y_value, x_button._value_min, x_button._value_max, level_range[level][0], level_range[level][1]);
    x_value = map(x_value, y_button._value_min, y_button._value_max, -100, 100);
}

void loop()
{
    static int begin = millis();
    menu.run();

    static int x_value = 0;
    static int y_value = 0;
    static int last_x_value = 0;
    static int last_y_value = 0;

    x_value = x_button.get_value();
    if (menu._speed == false)
        y_value = y_button.get_value();

    value_map(x_value, y_value, menu._level);

    if (client.connected())
    {
        int end = millis();
        if (end - begin > 20)
        {
            if (fabs(last_x_value - x_value) > 10 || fabs(last_y_value - y_value) > 10)
            {
                char buffer[24] = { 0 };
                sprintf(buffer, "x:%04d y:%04d\r\n", x_value, y_value);
                client.printf(buffer);
                Serial.printf(buffer);
                begin = end;
                last_x_value = x_value;
                last_y_value = y_value;
            }
        }
    }
    else
        menu.restart();
}

// 按键中断句柄
void button_handle()
{
    for (int i = 0; i < button_nums; ++i)
    {
        if (!digitalRead(buttons._button_pins[i]))
            buttons._button_map[i] = 1;
    }
}
